import type {
  ResourceOperation,
  ServiceName,
} from '#/api/daprplus/auth/resource';
import type { RoleNodeDto } from '#/api/daprplus/auth/role';
import type { FilterGroup } from '#/utils/daprplus/types';

import { computed, ref } from 'vue';

import { message } from 'ant-design-vue';
import { defineStore } from 'pinia';

import { getRoleNodeApi } from '#/api/daprplus/auth/role';
import { setFilterGroupsApi } from '#/api/daprplus/auth/role-authorize';
import { serviceInfoDict } from '#/utils/daprplus/constants';
import { ApiResultType, FilterOperate } from '#/utils/daprplus/types';

// 类型定义
interface FilterGroupState {
  [key: string]: Partial<Record<string, FilterGroup>>;
}

interface OperationState {
  [key: string]: string;
}

// 错误处理工具
const handleError = (error: unknown, customMessage: string) => {
  console.error(`${customMessage}:`, error);
  if (error instanceof Error) {
    message.error(`${customMessage}: ${error.message}`);
  } else {
    message.error(customMessage);
  }
};

export const useRoleAuthorizeStore = defineStore('roleAuthorize', () => {
  // 状态定义
  const roleNodes = ref<RoleNodeDto[]>([]);
  const loadingRoles = ref(false);
  const selectedRoleId = ref<null | string>(null);
  const selectedRole = ref<null | { id: string; name: string }>(null);
  const selectedService = ref<ServiceName>('IdentityApi');
  const roleAuthorizeOpen = ref(false);
  const rowFilterGroups = ref<FilterGroupState>({});
  const selectedOperation = ref<OperationState>({});

  // 计算属性
  const service = computed(
    () => serviceInfoDict[selectedService.value]?.value || 'identity-api',
  );

  // 角色管理相关方法
  async function loadRoleNodes(): Promise<void> {
    try {
      loadingRoles.value = true;
      const roles = await getRoleNodeApi();
      roleNodes.value = roles;
    } catch (error) {
      handleError(error, '加载角色列表失败');
    } finally {
      loadingRoles.value = false;
    }
  }

  function handleRoleSelect(role: RoleNodeDto): void {
    selectedRoleId.value = role.id;
    selectedRole.value = role;
  }

  // 资源操作相关方法
  function getResourceOperationColor(
    op: string,
    allowedOperations: ResourceOperation[],
  ): string {
    const item = allowedOperations.find((m) => m.code === op);
    return item?.color || 'default';
  }

  function getResourceOperationLabel(
    op: string,
    allowedOperations: ResourceOperation[],
  ): string {
    const item = allowedOperations.find((m) => m.code === op);
    return item?.display || op;
  }

  // 过滤条件管理相关方法
  function getOperationFilterGroup(
    rowId: string,
    operation: string,
  ): FilterGroup {
    if (!rowFilterGroups.value[rowId]) {
      rowFilterGroups.value[rowId] = {};
    }

    if (!rowFilterGroups.value[rowId][operation]) {
      rowFilterGroups.value[rowId][operation] = {
        groups: [],
        operate: FilterOperate.And,
        rules: [],
      };
    }

    return rowFilterGroups.value[rowId][operation] as FilterGroup;
  }

  function updateFilterGroup(
    rowId: string,
    operation: string,
    value: FilterGroup,
  ): void {
    if (!rowFilterGroups.value[rowId]) {
      rowFilterGroups.value[rowId] = {};
    }
    rowFilterGroups.value[rowId][operation] = value;
  }

  function initRowFilterGroup(row: {
    filterGroups?: Record<string, FilterGroup>;
    id?: string;
    operations?: string[];
  }): void {
    if (!row.id) return;

    const rowId = String(row.id);
    if (rowFilterGroups.value[rowId]) return;

    rowFilterGroups.value[rowId] = {};

    // 加载现有过滤条件
    if (row.filterGroups) {
      Object.entries(row.filterGroups).forEach(([operation, value]) => {
        if (rowFilterGroups.value[rowId]) {
          rowFilterGroups.value[rowId][operation] = value;
        }
      });
    }

    // 为每个操作创建默认过滤条件
    if (row.operations?.length) {
      row.operations.forEach((op) => {
        if (rowFilterGroups.value[rowId] && !rowFilterGroups.value[rowId][op]) {
          rowFilterGroups.value[rowId][op] = {
            groups: [],
            operate: FilterOperate.And,
            rules: [],
          };
        }
      });

      // 默认选中第一个操作
      if (row.operations[0] !== undefined) {
        selectedOperation.value[rowId] = row.operations[0];
      }
    }
  }

  async function saveFilterGroup(row: {
    id?: string;
    operations?: string[];
    resourceId: string;
    roleId: string;
  }): Promise<boolean> {
    if (!row.id) {
      message.error('无法保存过滤条件：资源ID缺失');
      return false;
    }

    const rowId = String(row.id);
    if (!rowFilterGroups.value[rowId]) {
      message.warning('没有可保存的过滤条件');
      return false;
    }

    try {
      const filterGroups: Record<string, FilterGroup> = {};

      if (row.operations?.length) {
        row.operations.forEach((op) => {
          if (
            rowFilterGroups.value[rowId] &&
            rowFilterGroups.value[rowId][op]
          ) {
            const group = rowFilterGroups.value[rowId][op] as FilterGroup;
            if (group.rules.length > 0 || group.groups.length > 0) {
              filterGroups[op] = group;
            }
          }
        });
      }

      const result = await setFilterGroupsApi(
        row.resourceId,
        row.roleId,
        filterGroups,
        service.value,
      );

      if (result.resultType === ApiResultType.Success) {
        message.success('过滤条件保存成功');
        return true;
      }

      message.error(`保存失败：${result.message}`);
      return false;
    } catch (error) {
      handleError(error, '保存过滤条件时发生错误');
      return false;
    }
  }

  // 状态重置
  function resetState(): void {
    rowFilterGroups.value = {};
    selectedOperation.value = {};
  }

  return {
    // 状态
    roleNodes,
    loadingRoles,
    selectedRoleId,
    selectedRole,
    selectedService,
    service,
    roleAuthorizeOpen,
    rowFilterGroups,
    selectedOperation,

    // 方法
    loadRoleNodes,
    handleRoleSelect,
    getResourceOperationColor,
    getResourceOperationLabel,
    getOperationFilterGroup,
    updateFilterGroup,
    initRowFilterGroup,
    saveFilterGroup,
    resetState,
  };
});
